package com.sergenis.miniapp.jpanel_imagenfondo;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;

public enum ImageScale {
	/**
	 * La imagen es ajustada para ocupar el alto del componente ( {@code heigth}
	 * ) centrando horizontalmente
	 */
	FILL,
	/**
	 * La imagen es ajustada para ocupar el ancho del componente ( {@code width}
	 * ) cientrando verticalmente
	 */
	SET,
	/**
	 * La imagen es ajustada para ocupar el ancho y alto del componente (
	 * {@code width & height})
	 */
	EXPAND,
	/**
	 * La imagen se muestra del tama�o priginal pero esta se muestra apartir de
	 * la pocicion (0, 0), <em>esquina superior izquierda</em>
	 */
	MOSAIC,
	/** Centra la imagen en el componente sin cambiar su tama original */
	CENTRE;
	
	public static BufferedImage getScaleImage(ImageScale is, Image img,
			int outWidth, int outHeigth) {
		return is.getScaleImage(img, outWidth, outHeigth);
	}
	
	ImageScale() {}
	
	public BufferedImage getScaleImage(Image img, int outWidth, int outHeigth) {
		BufferedImage buffImg;
		do { // Se forza a obtener un buffer de la imagen original
			buffImg = createOriginalBuffer(img);
		} while (buffImg == null);
		
		int inWidth = buffImg.getWidth();
		int inHeigth = buffImg.getHeight();
		double scaleX, scaleY;
		
		switch (this) {
		case FILL: {// Se define la escala en base alto [heigth].
			scaleX = ((double) outHeigth / inHeigth);
			scaleY = scaleX;
		}
			break;
		case SET: { // Se define la escala en base al ancho [width].
			scaleX = ((double) outWidth / inWidth);
			scaleY = scaleX;
		}
			break;
		case EXPAND: {// Se definen indivualmente la escala alto y ancho.
			scaleX = ((double) outWidth / inWidth);
			scaleY = ((double) outHeigth / inHeigth);
		}
			break;
		case CENTRE:
		case MOSAIC:
		default: {
			scaleX = 1.0;
			scaleY = 1.0;
		}
			break;
		}
		
		int wBuff = (int) (inWidth * scaleX);
		int hBuff = (int) (inHeigth * scaleY);
		
		BufferedImage outImage = new BufferedImage(wBuff, hBuff,
				BufferedImage.TYPE_INT_ARGB);
		Graphics2D g = outImage.createGraphics();
		AffineTransform at = AffineTransform.getScaleInstance(scaleX, scaleY);
		AffineTransformOp aop = new AffineTransformOp(at,
				AffineTransformOp.TYPE_BILINEAR);
		g.drawImage(buffImg, aop, 0, 0);
		g.dispose();
		
		return outImage;
	}
	
	private BufferedImage createOriginalBuffer(Image img) {
		BufferedImage buff = null;
		try {
			int w = img.getWidth(null);
			int h = img.getHeight(null);
			buff = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
			Graphics g = buff.getGraphics();
			g.drawImage(img, 0, 0, null);
			g.dispose();
		} catch (IllegalArgumentException iae) {}
		return buff;
	}
}
